package ch.fhnw.qualiscan.application.pages;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import ch.fhnw.qualiscan.Config;
import ch.fhnw.qualiscan.application.elements.BestPracticeForm;
import ch.fhnw.qualiscan.application.elements.QuestionForm;
import ch.fhnw.qualiscan.application.elements.QuestionHeader;
import ch.fhnw.qualiscan.application.models.DomainModel;
import ch.fhnw.qualiscan.application.models.QuestionModel;
import ch.fhnw.qualiscan.application.models.RoleModel;
import ch.fhnw.qualiscan.application.models.SurveyModel;
import ch.fhnw.qualiscan.application.models.UserModel;
import ch.fhnw.qualiscan.core.Page;
import ch.fhnw.qualiscan.core.db.pojos.Answer;
import ch.fhnw.qualiscan.core.db.pojos.BestPractice;
import ch.fhnw.qualiscan.core.db.pojos.Confidence;
import ch.fhnw.qualiscan.core.db.pojos.Domain;
import ch.fhnw.qualiscan.core.db.pojos.Question;
import ch.fhnw.qualiscan.core.db.pojos.Survey;
import ch.fhnw.qualiscan.core.db.pojos.SurveyUserRole;
import ch.fhnw.qualiscan.core.db.pojos.User;
import ch.fhnw.qualiscan.core.libraries.NotificationLib;

import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;

import eu.livotov.tpt.i18n.TM;
/**
 * Page to answer the questions.
 * 
 * @author Kevin Mettenberger, Benjamin Groehbiel
 *
 */
@SuppressWarnings("serial")
public class FillOut extends Page {
	
	private User user;
	private Domain currentDomain;
	private Survey currentSurvey;
	private DomainModel domainModel;
	private QuestionModel questionModel;
	private SurveyModel surveyModel;
	private RoleModel roleModel;
	private UserModel userModel;
	private List<QuestionForm> questionFormList;
	private int newConfidenceValue = 2;
	private BestPracticeForm bpf; 
	private ComboBox fillOutRole;
	private SurveyUserRole sur;
	
	Panel p1;
	Panel p2;
	Panel p3;
	
	@Override
	public void initModelsAndHelpers() {
		user = new User();
		user.setId(userSession.getId());
		domainModel = new DomainModel();
		questionModel = new QuestionModel();
		surveyModel = new SurveyModel();
		userModel = new UserModel();
		roleModel = new RoleModel();
		questionFormList = new ArrayList<QuestionForm>();
	}
	
	@Override
	public void buildLayout() {
		String domainName = domainModel.getDomainText(currentDomain, userSession.getLanguage()).getText();
		String surveyTitle = currentSurvey.getTitle();
	
		VerticalLayout fillOutWrapper = new VerticalLayout();
		fillOutWrapper.setSpacing(true);
		fillOutWrapper.setMargin(false, false, true, false);
		
		fillOutWrapper.addComponent(textHelper.h1(TM.get("fillout.title", domainName)));
		fillOutWrapper.addComponent(textHelper.p(TM.get("fillout.desc", surveyTitle)));
		
		addComponent(fillOutWrapper);
		
		p1 = new Panel();
		p1.addComponent(textHelper.h2(TM.get("fillout.questions.title")));
		
		// header
		HorizontalLayout header = new HorizontalLayout();
		header.setWidth("100%");
		
		HorizontalLayout headerForm = new HorizontalLayout();
		
		// first column (agree)
		Label c1 = new Label(TM.get("answer.1"));
		c1.setStyleName("answer1");
		c1.setHeight("100%");
		
		// second column 
		Label c2 = new Label(TM.get("answer.2"));
		c2.setStyleName("answer2");
		c2.setHeight("100%");
		
		// second column 
		Label c3 = new Label(TM.get("answer.3"));
		c3.setStyleName("answer3");
		c3.setHeight("100%");
		
		// second column 
		Label c4 = new Label(TM.get("answer.4"));
		c4.setStyleName("answer4");
		c4.setHeight("100%");
		
		// second column 
		Label c5 = new Label(TM.get("answer.5"));
		c5.setStyleName("answer5");
		c5.setHeight("100%");

		headerForm.addComponent(c1);
		headerForm.addComponent(c2);
		headerForm.addComponent(c3);
		headerForm.addComponent(c4);
		headerForm.addComponent(c5);
		headerForm.setWidth("290px");
		headerForm.setHeight("35px");
		headerForm.setStyleName("formColumns");
		
		Label headerSpacer = new Label("");
		header.addComponent(headerSpacer);
		header.addComponent(headerForm);
		header.setExpandRatio(headerSpacer, 1.0f);
		
		p1.addComponent(header);
	
		Iterator questionIterator = currentDomain.getQuestions().iterator();

		int counter = 0;
		int subCounter = 0;
		while (questionIterator.hasNext()) {
			subCounter = 0;
			counter++;
			Question currentQuestion = (Question) questionIterator.next();
			if(currentQuestion.getSubquestions().size() > 0) {
				//Question has subquestions
				p1.addComponent(new QuestionHeader(counter, questionModel.getQuestionText(userSession.getLanguage(),currentQuestion).getText(), false));
				Iterator subQuestionIterator = currentQuestion.getSubquestions().iterator();
				while(subQuestionIterator.hasNext()) {
					subCounter++;
					Question currentSubQuestion = (Question) subQuestionIterator.next();
					QuestionForm qf = new QuestionForm(questionModel.getAnswer(sur, currentSubQuestion),currentSubQuestion, counter, subCounter, questionModel.getQuestionText(userSession.getLanguage(),currentSubQuestion).getText(), true);
					questionFormList.add(qf);
					p1.addComponent(qf);
				}
			}
			else {
				//Question has no subquestion
				QuestionForm qf = new QuestionForm(questionModel.getAnswer(sur, currentQuestion),currentQuestion,counter, -1, questionModel.getQuestionText(userSession.getLanguage(),currentQuestion).getText(), false);
				questionFormList.add(qf);
				p1.addComponent(qf);
			}
		}
		addComponent(p1);
		
		// slider
		p2 = new Panel();
		
		Label sliderTitle = textHelper.h2(TM.get("fillout.slider.title"));
		Label sliderDesc = textHelper.p(TM.get("fillout.slider.desc"));
		
		List<Integer> answers = Arrays.asList(new Integer[] {1,2,3});
		
		OptionGroup confidenceOg = new OptionGroup(null, answers);
		confidenceOg.setItemCaption(1, TM.get("fillout.confidence.0"));
		confidenceOg.setItemCaption(2, TM.get("fillout.confidence.1"));
		confidenceOg.setItemCaption(3, TM.get("fillout.confidence.2"));
		confidenceOg.setStyleName("h-optiongroup confidenceCheckboxes");
		
		Confidence confidence = domainModel.getConfidenceOfDomain(sur, currentDomain);
		if (confidence != null) {
			confidenceOg.setValue(confidence.getConfidence());
		}
		else {
			confidenceOg.setValue(2);
		}
		confidenceOg.addListener(new Property.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				newConfidenceValue = (Integer) (event.getProperty().getValue());
			}
		});
		
		confidenceOg.setWidth("260px");
		
		HorizontalLayout sliderWrapper = new HorizontalLayout();
		sliderWrapper.addComponent(sliderDesc);
		sliderWrapper.addComponent(confidenceOg);
		sliderWrapper.setSpacing(true);
		sliderWrapper.setMargin(true);
		sliderWrapper.setWidth("100%");
		sliderWrapper.setExpandRatio(sliderDesc, 1.0f);
		
		p2.addComponent(sliderTitle);
		p2.addComponent(sliderWrapper);
		addComponent(p2);
		
		// best practice
		p3 = new Panel();
		
		bpf = new BestPracticeForm();
		BestPractice bp = domainModel.getBestPracticeOfDomain(sur, currentDomain);
		if (bp != null) {
			bpf.setValue(bp.getBestpractice(), bp.getTitle(), bp.getPublicpost());
		}
		p3.addComponent(bpf);
		addComponent(p3);
		
		/*
		 * Button and save algorithm
		 */
		Button saveButton = new Button(TM.get("fillout.save"), new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				
				event.getButton().setEnabled(false);
				event.getButton().setCaption(TM.get("action.saving"));
				
				// Save Answers
				for(int i = 0; i < questionFormList.size(); i++) {
					if(questionFormList.get(i).answer != 0) {
						Answer answer = questionModel.getAnswer(sur, questionFormList.get(i).question);
						if (answer == null) {
							Answer a = new Answer();
							a.setAnswer(questionFormList.get(i).answer);
							a.setSurvey(currentSurvey);
							a.setDomain(currentDomain);
							a.setUser(user);
							a.setSur(sur);
							
							questionModel.saveAnswer(a, questionFormList.get(i).question);
							
						}
						else {
							answer.setAnswer(questionFormList.get(i).answer);
							questionModel.updateAnswer(answer);
						}
					}
				}
				
				//Save Confidence
				Confidence confidence = domainModel.getConfidenceOfDomain(sur, currentDomain);
				if (confidence == null) {
					Confidence newConfidence = new Confidence();
					newConfidence.setConfidence(newConfidenceValue);
					newConfidence.setSurvey(currentSurvey);
					newConfidence.setSur(sur);
					newConfidence.setUser(user);
					
					domainModel.saveConfidenceOfDomain(newConfidence, currentDomain);
				}
				else {
					confidence.setConfidence(newConfidenceValue);
					domainModel.updateConfidenceOfDomain(confidence);
				}
				
				//Save BestPractice
				BestPractice bp = domainModel.getBestPracticeOfDomain(sur, currentDomain);
				if (bp == null) {
					BestPractice newbp = new BestPractice();
					newbp.setBestpractice(bpf.getTextValue());
					newbp.setPublicpost(bpf.getPublicValue());
					newbp.setTitle(bpf.getTitleValue());
					newbp.setEditdate(new java.util.Date());
					newbp.setSurvey(currentSurvey);
					newbp.setUser(user);
					newbp.setSur(sur);
					
					domainModel.saveBestPracticeOfDomain(newbp, currentDomain);
				}
				else {
					bp.setBestpractice(bpf.getTextValue());
					bp.setPublicpost(bpf.getPublicValue());
					bp.setTitle(bpf.getTitleValue());
					bp.setEditdate(new java.util.Date());
					domainModel.updateBestPracticeOfDomain(bp);
				}
				// scroll on top
				if (sur.getRole().getId() == Config.COORDINATOR_ID) {
					urlLib.setFragment("EditSurvey/1/"+sur.getId()+"",true);
				}
				else {
					urlLib.setFragment("EditSurvey/0/"+sur.getId()+"",true);
				}
				
			}
		});
		saveButton.setIcon(Config.ICON_EDIT_APP);
		
		HorizontalLayout button = new HorizontalLayout();
		button.addComponent(saveButton);
		button.setMargin(true, true, true, false);
		this.addComponent(button);
	}

	@Override
	public void setNeededPermissions() {
		 neededPermissions.add("loggedIn");
		 neededPermissions.add("fillout");
	}

	@Override
	public void initComponents() {
		

	}
	
	//Override initBuildLayout; buildLayout is called by thirdParameterChanged
	@Override
	public void initBuildLayout() {
		
	}

	@Override
	public void thirdParameterChanged(String thirdParameter) {
		removeAllComponents();
		
		int domainId;
		
		try {
			domainId = Integer.valueOf(thirdParameter).intValue();
		} catch(NumberFormatException ex) {
			NotificationLib.showError(TM.get("error"), TM.get("domain.error.exists"));
			return;
		}
		
		currentDomain = domainModel.getDomainById(domainId);
		if (currentDomain == null) {
			urlLib.setPage("Dashboard");
		}
		buildLayout();

	}
	
	@Override
	/**
	 * Is here used for getting the survey
	 */
	public void secondParameterChanged(int secondParameter) {
			sur = surveyModel.getSurById(secondParameter);
			if (sur == null) {
				urlLib.setPage("PermissionDenied");
			}
			
			currentSurvey = sur.getSurvey();
			if(currentSurvey != null) {
				if(!surveyModel.userParticipatesSurvey(currentSurvey, user)) {
					NotificationLib.showError(TM.get("error"), TM.get("survey.error.usernoparticipant"));
					urlLib.setPage("Dashboard");
				}
			}
			else {
				NotificationLib.showError(TM.get("error"), TM.get("survey.error.exists"));
				urlLib.setPage("Dashboard");
			}
	}

	
	

}
